/**
 * 
 */
package de.fsujena.chat_pi.user;

import java.io.*;
import java.util.*;

/**
 * @author Erik Hebestreit
 *
 */
public class UserManager {
	public HashMap<String,User> users = new HashMap<String,User>();
	public String filename = "userMap.dat";
	
	/**
	 * initialize UserManager
	 */
	public UserManager() {
		loadUserMap();
	}

	@SuppressWarnings("unchecked")
	public boolean loadUserMap() {
		// load existing users from database
		File file = new File(filename);
		
		if (file.exists()) {
			try {
				FileInputStream f = new FileInputStream(file);
				ObjectInputStream s = new ObjectInputStream(f);
				Object inputObject = s.readObject();
				
				if (inputObject instanceof HashMap<?,?>)
					this.users = (HashMap<String,User>) inputObject;
				
				s.close();
				return true;
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				return false;
			}
		} else {
			System.err.println("Failed to load users map.");
			return false;
		}		
	}
	
	/**
	 * method to create a new user from name and password
	 * 
	 * @return name of the user just created
	 */
	public String createUser(String name,String password) {
		//TODO: if not successful return false!?
		
		users.put(name,new User(name,password));
		this.saveUserMap();
		return name;
	}
	
	/**
	 * 
	 * @param name user name to be searched for
	 * @return user entry if user exists, <code>null</code> if user doesn't exist
	 */
	private User getUser(String name) {
		return users.get(name);
	}
	
	/**
	 * check if a certain entry exists
	 * 
	 * @param name user name to be searched for
	 * @return <b>true</b> if the entry exists, <b>false</b> if it does not exist
	 */
	public Boolean checkUserExists(String name) {
		return users.containsKey(name);
	}
	
	/**
	 * check the if the name-password combination is right
	 * 
	 * @param name user name to be searched for
	 * @param password password to be checked
	 * @return <b>true</b> if password is right, <b>false</b> if not
	 */
	public Boolean checkUserPassword(String name,String password) {
		return this.getUser(name).checkPassword(password);
	}
	
	/**
	 * changes the user name of a user with password authentication
	 * 
	 * @param name current user name
	 * @param password password of user
	 * @param newName new user name
	 * @return <b>true</b> if successful, <b>false</b> if not
	 */
	public Boolean changeUserName(String name,String password,String newName) {
		// check if password is right
		if (!this.checkUserPassword(name, password))
			return false;
		
		// set new name in user entry
		if (!this.getUser(name).setName(newName))
			return false;
		
		// put new key-value pair in HashMap to match new name
		users.put(newName, this.getUser(newName));
		// remove old HashMap entry
		users.remove(name);
		
		this.saveUserMap();
		
		return this.checkUserExists(newName);
	}
	
	public boolean saveUserMap() {
		File file = new File(filename);
		FileOutputStream f;
		ObjectOutputStream s;
		
		try {
			f = new FileOutputStream(file);
			s = new ObjectOutputStream(f);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		
		try {
			s.writeObject(this.users);
			s.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}

}
